package org.zjx.indetify.util;

import lombok.Data;
import org.zjx.entity.Rect;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

//方框识别工具
@Data
public class PaneUtil {
    public int extendDistance = 5;  // 向右和向下延伸的像素距离
    public int minLength = 10; // 颜色容忍度
    public List<Color> colorList;
    private BufferedImage image;

    public PaneUtil(BufferedImage image, int extendDistance, int minLength, List<Color> colorList) {
        this.image = image;
        this.extendDistance = extendDistance;
        this.minLength = minLength;
        this.colorList = colorList;
    }

    // 检测长方形区域
    public List<Rect> detectRect() {
        List<Rect> rects = new ArrayList<>();
        int width = image.getWidth();
        int height = image.getHeight();

        boolean[][] visited = new boolean[height][width]; // 标记已访问的区域

        // 遍历每个像素点，寻找长方形的左上角
        for (int y = 0; y < height - extendDistance * 2 - minLength; y++) {
            for (int x = 0; x < width - extendDistance * 2 - minLength; x++) {
                if (visited[y][x]) {
                    continue; // 已访问的像素点跳过
                }

                if (vertically_horizontal_non_color(image, x, y)) {
                    Point left_top = new Point(x, y);
                    Point right_top = perpetuateHorizontal(image, x, y);
                    Point left_bottom = perpetuateVertically(image, x, y);
                    if (right_top == null || left_bottom == null) {
                        visited[y][x] = true;
                        continue;
                    }
                    Point right_bottom = new Point(right_top.x, left_bottom.y);
                    extension(right_bottom);
                    boolean verify = verify(left_bottom, right_bottom, right_top);
                    if (verify) {
                        // 标记长方形区域，包括边线
                        // 水平方向从 left_top.x 到 right_top.x
                        for (int i = left_top.x; i <= right_top.x; i++) {
                            for (int j = left_top.y; j <= left_bottom.y; j++) {
                                visited[j][i] = true;
                            }
                        }

                        // 竖直方向从 left_top.y 到 left_bottom.y
                        for (int i = left_top.y; i <= left_bottom.y; i++) {
                            for (int j = left_top.x; j <= right_top.x; j++) {
                                visited[i][j] = true;
                            }
                        }

                        // 添加识别到的长方形区域
                        rects.add(new Rect(left_top.x, left_top.y, right_bottom.x, right_bottom.y));
                    }
                } else {
                    visited[y][x] = true;
                }
            }
        }

        return rects;
    }

    private void extension(Point right_bottom) {
        int x = right_bottom.x;
        int y = right_bottom.y;
        if (isColorMatch(new Color(image.getRGB(x - extendDistance, y))) && x >= image.getWidth()) {
            right_bottom = new Point(right_bottom.x + 1, right_bottom.y);
            extension(right_bottom);
        }
        if (isColorMatch(new Color(image.getRGB(x, y - extendDistance))) && y >= image.getHeight()) {
            right_bottom = new Point(right_bottom.x, right_bottom.y + 1);
            extension(right_bottom);
        }
    }

    private boolean verify(Point left_bottom, Point right_bottom, Point right_top) {
        for (int i = left_bottom.x + extendDistance; i <= right_bottom.x - extendDistance; i++) {
            if (!isColorMatch(new Color(image.getRGB(i, left_bottom.y)))) return false;
        }
        for (int i = right_top.y + extendDistance; i <= right_bottom.y - extendDistance; i++) {
            if (!isColorMatch(new Color(image.getRGB(right_top.x, i)))) return false;
        }
        return true;
    }

    //延续水平方向
    private Point perpetuateHorizontal(BufferedImage image, int x, int y) {
        for (int i = x + extendDistance; i <= image.getWidth() - extendDistance; i++) {
            if (!isColorMatch(new Color(image.getRGB(i, y)))) return new Point(i + extendDistance - 1, y);
        }
        return null;
    }

    //延续竖直方向
    private Point perpetuateVertically(BufferedImage image, int x, int y) {
        for (int i = y + extendDistance; i <= image.getHeight() - extendDistance; i++) {
            if (!isColorMatch(new Color(image.getRGB(x, i)))) return new Point(x, i + extendDistance - 1);
        }
        return null;
    }


    private boolean vertically_horizontal_non_color(BufferedImage image, int x, int y) {
        if (x < 0 || x >= image.getWidth() - extendDistance * 2 || y < 0 || y >= image.getHeight() - extendDistance * 2)
            return false;
        for (int i = 0; i < minLength; i++) {
            if (!isColorMatch(new Color(image.getRGB(x + extendDistance + i, y)))) return false;
            if (!isColorMatch(new Color(image.getRGB(x, y + extendDistance + i)))) return false;
        }
//        for (int i = 0; i < extendDistance; i++) {
//            if (isColorMatch(new Color(image.getRGB(x + i, y)))) return false;
//            if (isColorMatch(new Color(image.getRGB(x, y + i)))) return false;
//        }
        return true;
    }


    // 判断一个像素颜色是否匹配指定颜色
    private boolean isColorMatch(Color pixelColor) {
        boolean have = false;
        for (Color color : colorList) {
            if (color.equals(pixelColor)) {
                have = true;
                break;
            }
        }
        return have;
    }
}
